xend: XSPolicy.can_run xend support
authorKeir Fraser <keir.fraser@citrix.com>
Tue, 1 Apr 2008 09:08:03 +0000 (10:08 +0100)
committerKeir Fraser <keir.fraser@citrix.com>
Tue, 1 Apr 2008 09:08:03 +0000 (10:08 +0100)
Signed-off-by: Stefan Berger <stefanb@us.ibm.com>
tools/python/xen/util/xsconstants.py
tools/python/xen/util/xsm/acm/acm.py
tools/python/xen/xend/XendXSPolicy.py

index 856ef43acab19e34cd4afec5c063ac2a13bd3e36..730d66fbf5ac5874fd8272e5eed4666f307924b9 100644 (file)
@@ -57,7 +57,9 @@ XSERR_POLICY_NOT_LOADED        = 22 + XSERR_BASE
 XSERR_RESOURCE_ACCESS          = 23 + XSERR_BASE
 XSERR_HV_OP_FAILED             = 24 + XSERR_BASE
 XSERR_BOOTPOLICY_INSTALL_ERROR = 25 + XSERR_BASE
-XSERR_LAST                     = 25 + XSERR_BASE ## KEEP LAST
+XSERR_VM_NOT_AUTHORIZED        = 26 + XSERR_BASE
+XSERR_VM_IN_CONFLICT           = 27 + XSERR_BASE
+XSERR_LAST                     = 27 + XSERR_BASE ## KEEP LAST
 
 XSERR_MESSAGES = [
     '',
@@ -85,7 +87,9 @@ XSERR_MESSAGES = [
     'The policy is not loaded',
     'Error accessing resource',
     'Operation failed in hypervisor',
-    'Boot policy installation error'
+    'Boot policy installation error',
+    'VM is not authorized to run',
+    'VM label conflicts with another VM'
 ]
 
 def xserr2string(err):
index 98b6ec1312074f957e52a0b6f8e9f2cb950d8ba5..e8de0fa60c03927fa9b786cc8c11daa2bc455611 100644 (file)
@@ -68,6 +68,7 @@ policy_name_re = re.compile(".*[chwall|ste|chwall_ste].*", re.IGNORECASE)
 #decision hooks known to the hypervisor
 ACMHOOK_sharing = 1
 ACMHOOK_authorization = 2
+ACMHOOK_conflictset = 3
 
 #other global variables
 NULL_SSIDREF = 0
@@ -373,7 +374,7 @@ def label2ssidref(labelname, policyname, typ):
         else:
             return (sec_ssid[0] << 16) | pri_ssid[0]
     finally:
-       mapfile_unlock()
+        mapfile_unlock()
 
 
 def refresh_ssidref(config):
@@ -552,6 +553,18 @@ def hv_get_policy():
     return rc, bin_pol
 
 
+def is_in_conflict(ssidref):
+    """ Check whether the given ssidref is in conflict with any running
+        domain.
+    """
+    decision = acm.getdecision('ssidref', str(ssidref),
+                               'ssidref', str(ssidref),
+                               ACMHOOK_conflictset)
+    if decision == "DENIED":
+        return True
+    return False
+
+
 def set_policy(xs_type, xml, flags, overwrite):
     """
         Xend exports this function via XML-RPC
@@ -1550,6 +1563,33 @@ def get_security_label(self, xspol=None):
     return label
 
 
+def check_can_run(sec_label):
+    """ Check whether a VM could run, given its vm label. A VM can run if
+       - it is authorized
+       - is not in conflict with any running domain
+    """
+    try:
+        mapfile_lock()
+
+        if sec_label == None or sec_label == "":
+            vm_label = ACM_LABEL_UNLABELED
+        else:
+            poltype, policy, vm_label = sec_label.split(':')
+            if policy != get_active_policy_name():
+                return -xsconstants.XSERR_BAD_POLICY_NAME
+        ssidref = label2ssidref(vm_label, policy, 'dom')
+        if ssidref != xsconstants.INVALID_SSIDREF:
+            if not has_authorization(ssidref):
+                return -xsconstants.XSERR_VM_NOT_AUTHORIZED
+            if is_in_conflict(ssidref):
+                return -xsconstants.XSERR_VM_IN_CONFLICT
+            return -xsconstants.XSERR_SUCCESS
+        else:
+            return -xsconstants.XSERR_BAD_LABEL
+    finally:
+        mapfile_unlock()
+
+
 __cond = threading.Condition()
 __script_runner = None
 __orders = []
index dff029ddde2832898d6cb5717463b49d0c71abeb..0b6d5bc388b03fe1b66c135872577562f9fe2cf7 100644 (file)
@@ -48,7 +48,8 @@ class XendXSPolicy(XendBase):
                   'rm_xsbootpolicy',
                   'get_resource_label',
                   'set_resource_label',
-                  'get_labeled_resources' ]
+                  'get_labeled_resources',
+                  'can_run' ]
         return XendBase.getFuncs() + funcs
 
     getClass    = classmethod(getClass)
@@ -190,6 +191,12 @@ class XendXSPolicy(XendBase):
         res = security.get_resource_label_xapi(resource)
         return res
 
+    def can_run(self, sec_label):
+        irc = security.validate_label_xapi(sec_label, 'dom')
+        if irc != xsconstants.XSERR_SUCCESS:
+            raise SecurityError(irc)
+        return security.check_can_run(sec_label)
+
     get_xstype      = classmethod(get_xstype)
     get_xspolicy    = classmethod(get_xspolicy)
     set_xspolicy    = classmethod(set_xspolicy)
@@ -198,6 +205,7 @@ class XendXSPolicy(XendBase):
     set_resource_label = classmethod(set_resource_label)
     get_resource_label = classmethod(get_resource_label)
     get_labeled_resources = classmethod(get_labeled_resources)
+    can_run = classmethod(can_run)
 
 
 class XendACMPolicy(XendXSPolicy):